// <copyright file="RadioButtonList.cs" company="YUIAsp.Net">
// Copyright (c) 2009 All Right Reserved
// </copyright>
// <author>raul popescu</author>
// <email>dev@yuiasp.net</email>
// <date>2009-01-30</date>
// <summary>YUIAsp.Net File</summary>

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI;
using YUIAspNet.Common;

[assembly: WebResource("YUIAspNet.Button.RadioButtonList.js", "text/javascript")]

namespace YUIAspNet
{
    /// <summary>
    /// RadioButton display for the Button.
    /// </summary>
    public class RadioButtonList : YUIScriptBaseControl, INamingContainer, IPostBackDataHandler
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="RadioButtonList"/> class.
        /// </summary>
        public RadioButtonList()
        {
            this.PreRender += new EventHandler(RadioButtonList_PreRender);
            ApplyTheme();
        }

        private void ApplyTheme()
        {
            this.CssClass = YUITHEME_CSSCLASS;
        }

        #region Page Events

        void RadioButtonList_PreRender(object sender, EventArgs e)
        {
            if ((this.Page != null))
                this.Page.RegisterRequiresPostBack(this);
        } 
        #endregion

        #region Public properties
        /// <summary>
        /// Get / set the client side click handler.
        /// Handler gets 2 parameters: the sender(instance of the Button client side class) and arguments.
        /// </summary>
        public string OnClientCheckChange
        {
            get { return ViewState["OnClientCheckChange"] as string; }
            set { ViewState["OnClientCheckChange"] = value; }
        }

        /// <summary>
        /// Get / set the button's radio button items.
        /// This property is considered when button's type is Radio
        /// </summary>
        [Category("Data"), Description("Button options.")]
        [DefaultValue((string)null), PersistenceMode(PersistenceMode.InnerProperty), MergableProperty(false), NotifyParentProperty(true)]
        public RadioButtonItemCollection Items
        {
            get { return (RadioButtonItemCollection)Controls; }
        }

        /// <summary>
        /// Gets or sets the selected value.
        /// </summary>
        /// <value>The selected value.</value>
        public string SelectedValue { get; set; }

        /// <summary>
        /// Gets or sets the selected item.
        /// </summary>
        /// <value>The selected item.</value>
        public RadioButtonItem SelectedItem { get; set; } 
        #endregion

        #region Internal functionality

        /// <summary>
        /// Register the values to send to the client control for initialization.
        /// </summary>
        protected override void RegisterClientInitialization() 
        {
            this.Page.ClientScript.RegisterHiddenField(this.ClientID + "_state", this.SelectedValue);

            if (!string.IsNullOrEmpty(this.OnClientCheckChange))
                AddEvent("onCheckChange", this.OnClientCheckChange);

            List<RadioButtonItemClient> clientItemList = new List<RadioButtonItemClient>();
            RadioButtonItemClient clientItem;

            foreach (RadioButtonItem btn in this.Items)
            {
                clientItem = new RadioButtonItemClient();

                clientItem.Checked = btn.Checked;
                clientItem.Label = btn.Text;
                clientItem.Value = btn.Value;

                clientItemList.Add(clientItem);
            }

            AddProperty("Items", clientItemList);
        }

        /// <summary>
        /// Registers any additional scripts to include for this control.
        /// </summary>
        protected override void RegisterScriptReferences() 
        {
            AddScriptReference(new ScriptReference("YUIAspNet.Button.RadioButtonList.js", typeof(Button).Assembly.FullName));
        }

        /// <summary>
        /// Registers the style sheets for the current control.
        /// Must be overriden in the parent control to add any css file reference.
        /// </summary>
        protected override void RegisterStyleSheets()
        {
            this.RegisterEmbeddedStylesheet("Button", "button.css");
        }

        /// <summary>
        /// Creates a new <see cref="T:System.Web.UI.ControlCollection"/> object to hold the child controls (both literal and server) of the server control.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Web.UI.ControlCollection"/> object to contain the current server control's child server controls.
        /// </returns>
        protected override ControlCollection CreateControlCollection()
        {
            return new RadioButtonItemCollection(this);
        }

        /// <summary>
        /// Called after a child control is added to the <see cref="P:System.Web.UI.Control.Controls"/> collection of the <see cref="T:System.Web.UI.Control"/> object.
        /// </summary>
        /// <param name="control">The <see cref="T:System.Web.UI.Control"/> that has been added.</param>
        /// <param name="index">The index of the control in the <see cref="P:System.Web.UI.Control.Controls"/> collection.</param>
        /// <exception cref="T:System.InvalidOperationException">
        /// 	<paramref name="control"/> is a <see cref="T:System.Web.UI.WebControls.Substitution"/>  control.</exception>
        protected override void AddedControl(Control control, int index)
        {
            RadioButtonItem item = (RadioButtonItem)control;

            //item was added -> if item checked, unckeck all previous items.
            if (item.Checked)
            {
                foreach (RadioButtonItem existingItem in this.Items)
                {
                    if (existingItem != item)
                        existingItem.Checked = false;
                }
            }

            item.ResetCheck += new EventHandler(item_ResetCheck);

            base.AddedControl(control, index);
        }

        void item_ResetCheck(object sender, EventArgs e)
        {
            foreach (RadioButtonItem item in this.Items)
            {
                item.Checked = false;
            }
        }

        #region IPostBackDataHandler Members

        /// <summary>
        /// When implemented by a class, processes postback data for an ASP.NET server control.
        /// </summary>
        /// <param name="postDataKey">The key identifier for the control.</param>
        /// <param name="postCollection">The collection of all incoming name values.</param>
        /// <returns>
        /// true if the server control's state changes as a result of the postback; otherwise, false.
        /// </returns>
        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            if (!string.IsNullOrEmpty(postCollection[this.ClientID + "_state"]))
            {
                this.SelectedValue = postCollection[this.ClientID + "_state"];

                foreach (RadioButtonItem item in this.Items)
                {
                    if (item.Value == postCollection[this.ClientID + "_state"])
                    {
                        this.SelectedItem = item;
                        break;
                    }
                }

                if(this.SelectedItem != null)
                    this.SelectedItem.Checked = true;
            }

            return false;
        }

        /// <summary>
        /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
        /// </summary>
        public void RaisePostDataChangedEvent()
        {

        }

        #endregion 
        #endregion
    }
}

